package com.example.housingRentalSystem.security.provider;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
import java.util.List;

@Component
public class JwtTokenProvider {

    private static final Logger logger = LoggerFactory.getLogger(JwtTokenProvider.class);

    @Value("${jwt.secret}")
    private String secretKey;

    @Value("${jwt.token-validity-in-seconds}")
    private long validityInSeconds;

    private Key key;

    @PostConstruct
    public void init() {
        byte[] keyBytes = DatatypeConverter.parseBase64Binary(secretKey);

        this.key = new SecretKeySpec(keyBytes, SignatureAlgorithm.HS256.getJcaName());
        logger.info("JWT 密钥已加载，长度: {} 字符", secretKey.length());
        logger.debug("密钥内容: {}", secretKey);
    }

    public String createToken(Integer id,String account, List<String> roles) {
        Claims claims = Jwts.claims().setSubject(account);
        claims.put("account", account);
        claims.put("roles", roles);
        claims.put("id", id);
        Date now = new Date();
        Date validity = new Date(now.getTime() + validityInSeconds * 1000);

        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(now)
                .setExpiration(validity)
                .signWith(SignatureAlgorithm.HS256, key)
                .compact();
    }
    public String getUsernameFromToken(String token) {
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
    }


    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 从令牌中获取用户ID
     */
    public Integer getUserIdFromToken(String token) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(token)
                    .getBody();
            return claims.get("id", Integer.class);
        } catch (Exception e) {
            logger.error("解析用户ID失败，令牌可能已过期或被篡改: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 解析请求头中的令牌
     */
    public String resolveToken(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }

    public Integer getUserIdFromRequest(HttpServletRequest request) {
        String token = this.resolveToken(request);
        if (token != null && this.validateToken(token)) {
            return this.getUserIdFromToken(token);
        }
        logger.warn("无效或缺失的JWT令牌，请求路径: {}", request.getRequestURI());
        return null;
    }
}